package com.ylz.sjzx.sio.room.config;

import com.corundumstudio.socketio.SocketConfig;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import com.ylz.sjzx.sio.common.core.utils.HostUtil;
import com.ylz.sjzx.sio.common.mid.cache.redis.JedisTemplate;
import com.ylz.sjzx.sio.common.core.context.ApplicationUtils;
import com.ylz.sjzx.sio.common.core.enums.Cmd;
import com.ylz.sjzx.sio.sdk.client.core.IMNioService;
import com.ylz.sjzx.sio.sdk.client.core.socketio.IMSocketIOChannelInitializer;
import com.ylz.sjzx.sio.sdk.client.core.socketio.ImSocketIOServer;
import io.netty.util.NettyRuntime;
import io.netty.util.internal.SystemPropertyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@Configuration
public class IMConfig implements ApplicationListener<ContextRefreshedEvent> {
    @Value("${im.web.socketIoPort}")
    private int socketIoPort;

    @Value("${im.socketio.bossCount}")
    private int bossCount;

    @Value("${im.socketio.workCount}")
    private int workCount;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Bean(destroyMethod = "destroy")
    public IMNioService getNioSocketAcceptor() {

        return new IMNioService.Builder()
                //.setSocketIoPort(this.socketIoPort)
                .setWebsocketPort(12233)
                .build();

    }

    /**
     * netty-socketio服务器
     */
    @Bean
    public SocketIOServer socketIOServer() {
        SocketConfig socketConfig = new SocketConfig();
        socketConfig.setTcpKeepAlive(true);

        com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
        config.setSocketConfig(socketConfig);
        config.setHostname(HostUtil.getHostAddress());
        config.setPort(this.socketIoPort);
        log.info("bossCount" + this.bossCount);
        log.info("workCount" + this.workCount);
        config.setBossThreads(this.bossCount);
        config.setWorkerThreads(this.workCount);
        //config.setPreferDirectBuffer(false);

        log.info("netty default thread{}", SystemPropertyUtil.getInt(
                "io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
        SocketIOServer server = new ImSocketIOServer(config);
        for (Cmd cmd : Cmd.values()) {
            if (Cmd.disableUser == cmd) {
                continue;
            }
            server.addEventListener(cmd.getValue(), Object.class, (client, data, ackSender) -> {
                log.debug("addEventListener{}", data);
            });
        }
        server.setPipelineFactory(new IMSocketIOChannelInitializer());
        return server;
    }

    /**
     * 用于扫描netty-socketio的注解，比如 @OnConnect、@OnEvent
     */
    @Bean
    public SpringAnnotationScanner springAnnotationScanner() {
        return new SpringAnnotationScanner(this.socketIOServer());
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        log.info("项目正常部署2");
        JedisTemplate.me().setRedisTemplate(this.redisTemplate);
        ApplicationUtils.getBean(IMNioService.class).bind();

    }
}
